/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package ebookmgr;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreeModel;

/**
 * Created by ma.zhao@dl.cn. User: mazhao Date: 2009-9-6 Time: 15:29:50 Welcome
 * to Dalian.
 */
public class TreeUtil {

    // 4 blank for one level.
    private static final String LEVEL_SEP = "    ";
    // separator between name and keywords.
    private static final String LINE_SEP = ":";

    //====================
    // load tree section
    //====================
    public static TreeModel loadTree(){
        BufferedReader br = null;
        TreeModel tm = null;
        try {

            br = new BufferedReader(new FileReader(Configuration.getConfFilePath()));


            DefaultMutableTreeNode root = new DefaultMutableTreeNode();

            String line = null;
            // add each line
            while ((line = br.readLine()) != null) {
                int level = getLevel(line);
                String[] items = line.split(LINE_SEP);
                CatalogUserObject userObject = new CatalogUserObject(items[0].trim(),
                        items[1].trim());
                if (level == 0) {
                    root.setUserObject(userObject);
                } else {
                    addNode(root, userObject, level);
                }
            }

            tm = new DefaultTreeModel(root);
        } catch(IOException ex){
            EBookMgrUtil.showMessageAndExit("Can not load catalog tree, message is:" + ex.getMessage());
        } finally {
            EBookMgrUtil.safelyClose(br);
        }
        return tm;
    }

    private static int getLevel(String str) {
        int level = 0;
        while (str.startsWith(LEVEL_SEP)) {
            level++;
            str = str.substring(LEVEL_SEP.length());
        }

        return level;
    }

    private static void addNode(DefaultMutableTreeNode root,
            CatalogUserObject items, int level) {

        // find target tree node.
        DefaultMutableTreeNode targetNode = root;
        int still = level - 1;
        while (still > 0) {
            // get last child until to level - 1;
            targetNode = (DefaultMutableTreeNode) targetNode.getLastChild();
            still--;
        }

        targetNode.add(new DefaultMutableTreeNode(items));
    }

    //====================
    // save tree section
    //====================
    public static void saveTree(TreeModel tm) {

        // get strng from tree
        DefaultMutableTreeNode root = (DefaultMutableTreeNode) tm.getRoot();
        StringBuilder sb = new StringBuilder();
        appendUserObject(sb, root, 0);

        System.out.println("tree model to string is:");
        System.out.println(sb.toString());

        BufferedWriter br = null;
        try {
            br = new BufferedWriter(new FileWriter(Configuration.getConfFilePath()));
            br.write(sb.toString());
        } catch (IOException ex) {
            EBookMgrUtil.showMessageAndExit("Can not save catalog, message is:" + ex.getMessage());
        } finally {
            EBookMgrUtil.safelyClose(br);
        }

    }

    private static void appendUserObject(StringBuilder sb, DefaultMutableTreeNode node, int level) {
        StringBuilder prefix = new StringBuilder();
        
        // add level separator
        for (int i = 0; i < level; i++) {
            prefix.append(LEVEL_SEP);
        }

        CatalogUserObject obj = (CatalogUserObject) node.getUserObject();

        prefix.append(obj.getName()).append(LINE_SEP).append(obj.getKeyword());

        sb.append(prefix.toString()).append(System.getProperty("line.separator"));

        int childCnt = node.getChildCount();
        for (int i = 0; i < childCnt; i++) {
            DefaultMutableTreeNode child = (DefaultMutableTreeNode) node.getChildAt(i);
            appendUserObject(sb, child, level + 1);
        }

    }
}
